home *** CD-ROM | disk | FTP | other *** search
/ SGI Hot Mix 17 / Hot Mix 17.iso / HM17_SGI / research / lib / obsolete / widalloc.pro < prev    next >
Text File  |  1997-07-08  |  9KB  |  296 lines

  1. ;
  2. ; $Id: widalloc.pro,v 1.9 1997/01/15 03:11:50 ali Exp $
  3. ;
  4. ;  WidAlloc
  5. ;   Widget Editor allocation related routines.
  6. ;
  7. ; Copyright (c) 1993-1997, Research Systems, Inc.  All rights reserved.
  8. ;   Unauthorized reproduction prohibited.
  9. ;
  10. ; MODIFICATION HISTORY
  11. ;       Written by:     Joshua Goldstein,       12/93
  12. ;
  13.  
  14.  
  15.  
  16. ;
  17. ;  Destroy
  18. ;   Generic function to cause an object to delete itself from memory.
  19. ;   This is assumed to be recursive (objects containing other objects
  20. ;   should destroy their children as well).
  21. ;
  22. PRO Destroy, Ptr
  23.  
  24.     ;   An invalid pointer is considered to be already destroyed
  25.     ;   Not much we could do anyway.
  26.     IF WIDGET_INFO(Ptr, /VALID_ID) EQ 0 THEN RETURN
  27.  
  28.     ;   Figure out the class specific routine name and call it
  29.     GetType, Ptr, Type
  30.     CALL_PROCEDURE,Type+"_Destroy",Ptr
  31. END
  32.  
  33.  
  34. ;
  35. ;  GenDestroy
  36. ;   Generic Object destruction routine.
  37. ;
  38. PRO GenDestroy, Ptr, HASVALUE=HasValue
  39.     Ptr2Obj, Ptr, Obj
  40.  
  41.     IF N_ELEMENTS(Obj) EQ 0 THEN RETURN
  42.  
  43.     IF KEYWORD_SET(HasValue) THEN $
  44.         WIDGET_CONTROL, Obj.Value1, /DESTROY    ; Destroy value contents
  45.  
  46.     IF WIDGET_INFO(Obj.Dialog, /VALID) THEN $   ; Destroy dialog box
  47.         WIDGET_CONTROL, Obj.Dialog, /DESTROY
  48.  
  49.     WIDGET_CONTROL, Ptr, /DESTROY               ; Release pointer memory
  50.     ;   Object is in local variable and goes away as we return
  51. END
  52.  
  53.  
  54. ;
  55. ;  GenCopy
  56. ;   Copy an object.  2 copy methods:
  57. ;
  58. ;   if( copy != NULL)       { *copy = *ptr; free(ptr); }
  59. ;   else                    { *(copy = malloc(...)) = *ptr; }
  60. ;
  61. PRO GenCopy, Ptr, Copy, HASVALUE=HasValue
  62.   COMMON WidEd_Comm
  63.  
  64.     IF KEYWORD_SET(Copy) THEN BEGIN     ; Copy is already allocated
  65.  
  66.         Ptr2Obj, Copy, ThrowAway        ; Release current copy contents
  67.  
  68.         IF KEYWORD_SET(HasValue) THEN $
  69.             WIDGET_CONTROL, ThrowAway.Value1, /DESTROY  ; Destroy value too
  70.  
  71.         Ptr2Obj, Ptr, Obj               ; Remove object from original pointer
  72.         Obj2Ptr, Obj, Copy              ; Store in copy pointer
  73.         WIDGET_CONTROL, Ptr, /DESTROY   ; Release original pointer memory
  74.  
  75.     ENDIF ELSE BEGIN
  76.  
  77.         Ptr2Obj, Ptr, Obj, /COPY        ; Make a copy of ptr contents
  78.  
  79.         IF KEYWORD_SET(HasValue) THEN $
  80.             Ptr2Obj, Obj.Value1, Value1, /COPY  ; Get copy of value1 contents
  81.  
  82.         Copy    = WIDGET_BASE(GROUP=TopDlg)     ; Make a new pointer
  83.  
  84.         IF KEYWORD_SET(HasValue) THEN BEGIN
  85.             Obj.Value1  = WIDGET_BASE(GROUP=TopDlg) ; New ptr for value
  86.             IF N_ELEMENTS(Value1) NE 0 THEN $
  87.                 Obj2Ptr, Value1, Obj.Value1     ; Save value
  88.         ENDIF
  89.  
  90.         Obj.Id  = NewId()
  91.         Obj2Ptr, Obj, Copy              ; Store copy into new pointer
  92.  
  93.     ENDELSE
  94. END
  95.  
  96.  
  97. ;
  98. ;  Ptr2Obj
  99. ;   Pointers are really unrealized base widget objects and the
  100. ;   contents are their UVALUEs.  In general, copying structures is
  101. ;   an expensive operation so the default is to REMOVE the UVALUE
  102. ;   from the pointer.  This is much faster.  Note that is has the
  103. ;   side effect that the pointer is no longer valid (has no object
  104. ;   in it).
  105. ;
  106. PRO Ptr2Obj, Ptr, Obj, COPY=Copy
  107.     WIDGET_CONTROL, Ptr, GET_UVALUE=Obj, NO_COPY=(1 - KEYWORD_SET(Copy))
  108. END
  109.  
  110.  
  111. ;
  112. ;  Obj2Ptr
  113. ;   The reverse of Ptr2Obj.  Place the given object (as a UVALUE) into
  114. ;   the given pointer (unrealized base widget).  Copy the value if
  115. ;   explicitly requested, otherwise the Object given us will no longer
  116. ;   contain a value upon return from this function.
  117. ;
  118. PRO Obj2Ptr, Obj, Ptr, COPY=Copy
  119.     WIDGET_CONTROL, Ptr, SET_UVALUE=Obj, NO_COPY=(1 - KEYWORD_SET(Copy))
  120. END
  121.  
  122.  
  123. ;
  124. ;  NextPtr
  125. ;   Returned the contents of the .Next field of an object.  All objects
  126. ;   must have a .Next field.
  127. ;
  128. FUNCTION NextPtr, Ptr
  129.     Ptr2Obj, Ptr, Obj
  130.     Next    = Obj.Next
  131.     Obj2Ptr, Obj, Ptr
  132.     RETURN, Next
  133. END
  134.  
  135.  
  136. ;
  137. ;  AddChild
  138. ;       Add an object to a base object.
  139. ;
  140. ;   NO_UPDATE -- If set, DONT call the routine to update the Cut/Copy/Paste
  141. ;           dialog boxes.  Set when adding multiple objects (as in File Open)
  142. ;
  143. ;   NO_CANCEL -- If set the object is not added to the Active dialog
  144. ;           list.  This is done for base objects (Base Object Dialog boxes
  145. ;           have no CANCEL button) and should be done for any object class
  146. ;           which can not/should not be removed.
  147. ;
  148. PRO AddChild, Parent, Child, NO_UPDATE=NoUpdate, NO_CANCEL=NoCancel
  149.  
  150.   COMMON WidEd_Comm
  151.  
  152.     ;   Set Parent Ptr in child
  153.     SetTag, Child, "Parent", Parent
  154.  
  155.     ;   Get the Parent object structure
  156.     Ptr2Obj, Parent, PObj
  157.  
  158.     ;   First Child ? Set parent child list.
  159.     ;   Else last child in list now has a next child
  160.     ;
  161.     IF PObj.Children EQ 0 THEN PObj.Children    = Child $
  162.     ELSE SetTag, PObj.LastChild, "Next", Child
  163.  
  164.     ;   Remember the last child
  165.     PObj.LastChild  = Child
  166.  
  167.     Obj2Ptr, PObj, Parent       ; Restore structure into parent pointer
  168.  
  169.     ;   Add to active dialog list so we can delete it in the event
  170.     ;   user CANCELs addition.
  171.     IF KEYWORD_SET(NoCancel) EQ 0 THEN BEGIN
  172.         NewDialogs  = [ NewDialogs, { WE_NEWOBJ, Parent, Child, 0L } ]
  173.     ENDIF
  174.  
  175.     ;   Update Cut/Copy/Paste/Edit Dialog boxes
  176.     IF KEYWORD_SET(NoUpDate) EQ 0 THEN UpdateEdit
  177.  
  178.     ;   Note that the object tree has been altered.
  179.     Dirty   = 1
  180. END
  181.  
  182.  
  183. ;
  184. ;  Cancel
  185. ;   Common routine to handle the 'CANCEL' button on dialog boxes.
  186. ;   This performs 2 separate actions depending upon what has happened
  187. ;   so far:
  188. ;
  189. ;   If the object has been added but never realized (no Rebuild) then
  190. ;   OldPtr is NULL and there is no state to revert the widget to.
  191. ;   Otherwise, we have a copy of the widgets previous state and we
  192. ;   restore it instead of deleting it.
  193. ;
  194. ;   Note: The object information has already been pulled out of the pointer
  195. ;   so we need both to be passed in.
  196. ;
  197. PRO Cancel, Obj, Ptr
  198.  
  199.   COMMON WidEd_Comm    
  200.  
  201.     Type    = Obj.Type      ; Get the type
  202.     Dialog  = Obj.Dialog    ; Get the Dialog Box widget Id.
  203.     Obj2Ptr, Obj, Ptr       ; Stick Object back into pointer so that
  204.                             ; other routines can access object via its ptr
  205.  
  206.     ;   See if this object can be cancelled. Should always be found.
  207.     ;   In fact we display an error message if we don't
  208.  
  209.     Idx = WHERE(NewDialogs.ObjPtr EQ Ptr, Count)
  210.  
  211.     IF Count NE 1 THEN ErrorDialog, TopDlg, $
  212.         "Internal Error: CANCEL'ed widget could not be found"
  213.  
  214.     ;   Do we have an previous version of this widget to revert to?
  215.  
  216.     Idx = Idx[0]
  217.     IF NewDialogs[Idx].OldPtr NE 0L THEN BEGIN
  218.  
  219.         ;   Call class specific copy routine to revert object to
  220.         ;   its previous state:  *ObjPtr = *OldPtr
  221.  
  222.         CALL_PROCEDURE, Type + "_Copy", NewDialogs[Idx].OldPtr, $
  223.                     NewDialogs[Idx].ObjPtr
  224.         WIDGET_CONTROL, Dialog, /DESTROY    ; Take down dialog box
  225.  
  226.     ENDIF ELSE BEGIN
  227.  
  228.         ;   This is more difficult.  Remove the object from its
  229.         ;   parent's list of children
  230.  
  231.         ParPtr  = NewDialogs[Idx].ParPtr        ; Get Parent Object
  232.         Ptr2Obj, ParPtr, ParObj
  233.  
  234.         ;   Is it the first child?
  235.         IF ParObj.Children EQ Ptr THEN BEGIN
  236.             ParObj.Children = NextPtr(Ptr)
  237.  
  238.             ;   Was it an only child?
  239.             IF ParObj.LastChild EQ Ptr THEN ParObj.LastChild = ParObj.Children
  240.  
  241.         ENDIF ELSE BEGIN
  242.  
  243.  
  244.             PrevPtr = ParObj.Children           ; Run down the list of children
  245.             CurrPtr = NextPtr(PrevPtr)          ; until we find the child in
  246.             NxtPtr  = NextPtr(Ptr)              ; question. Keep track of the
  247.             WHILE CurrPtr NE Ptr DO BEGIN       ; previous child.
  248.                 PrevPtr = CurrPtr
  249.                 CurrPtr = NextPtr(CurrPtr)
  250.             ENDWHILE
  251.  
  252.             ; Unlink the deleted child from the list of children
  253.             ; If it was the last child of the parent object then set
  254.             ; the LastChild field to the new last child.
  255.             SetTag, PrevPtr, "Next", NxtPtr
  256.             IF ParObj.LastChild EQ Ptr THEN ParObj.LastChild = PrevPtr
  257.  
  258.         ENDELSE
  259.  
  260.         Obj2Ptr, ParObj, ParPtr     ; Restore Parent pointer
  261.  
  262.         ;   The child has been removed from the object tree. Delete
  263.         ;   the child.
  264.         CALL_PROCEDURE, Type + "_Destroy", Ptr  ; Destroy Object
  265.     ENDELSE
  266.  
  267.     ;   Now we have to remove the deleted object from the list
  268.     ;   of objects with active dialog boxes.
  269.  
  270.     N   = N_ELEMENTS(NewDialogs)
  271.     IF Idx[0] EQ N-1 THEN $                 ; Last active object?
  272.         NewDialogs  = NewDialogs[0:N-2] $
  273.     ELSE $
  274.         NewDialogs  = [ NewDialogs[0:Idx-1], NewDialogs[Idx+1,*] ]
  275.     UpdateEdit
  276. END
  277.  
  278.  
  279. ;
  280. ;  Accept
  281. ;   The user has pressed the 'DONE' button or just closed the dialog
  282. ;   box via the window manager menu Close option.  Unfortunately these
  283. ;   look like 'DONE's and not 'CANCEL's. Thats what documentation is for.
  284. ;
  285. ;   Note: as with Cancel, the Object structure is already outside of
  286. ;       the pointer
  287. ;       Unlike Cancel, Base Objects also need to be handled (not that
  288. ;       this makes any difference here)
  289. ;
  290. PRO Accept, Obj, Ptr
  291.     Obj2Ptr, Obj, Ptr       ; Stick Object back into pointer
  292. END
  293.  
  294. PRO WidAlloc
  295. END
  296.